package com.cskaoyan.javse.oop2._2polymorphic._1basic._3advantage;

import com.sun.media.jfxmedia.events.NewFrameEvent;

/**
 * 多态的优缺点:
 * 科学家要收集动物的叫声去研究，先要收集猫，狗两种动物的叫声研究。
 * 随后又扩展到其它动物，最后又需要研究人类。
 *
 * 这个过程中,如果一种动物写一个方法实现功能,就过于麻烦了.那么能不能写一个方法,把所有动物都研究了呢?
 *
 * 多态的优点:
 *      1. 要实现多态必须要继承，而继承提高了代码复用率，提升了程序的可维护性。（继承保证）
 *      2. 有了多态后，用父类引用指向不同子类对象，只需要调用同名方法，就能自动根据不同子类对象，得出不同的行为。这大幅度简化了代码，提升了程序的扩展性。（多态保证）
 *
 * 多态的缺点:
 *      父类引用限制了子类对象的功能,父类引用不能直接访问子类中独有的成员
 *
 *
 * 
 * @since 17:14
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
    public static void main(String[] args) {
        collectAnimalVoice(new Cat());
        collectAnimalVoice(new Dog());
        collectAnimalVoice(new Pig());
        collectAnimalVoice(new Person());
    }

    // 研究猫
    /*public static void collectCatVoice(Cat c){
        // 抓一只猫来
        c.shout();
        //收集研究
    }*/

    // 写一个方法,方法的形参是Animal a
    // 传入子类对象 相当于父类引用指向子类对象
    // 如果方法的形参是一个引用数据类型(类),那么方法传入的实参可以是它的对象或者子类对象
    public static void collectAnimalVoice(Animal a){
        // 这里如果想要加钱,必须先把Animal引用转换为Person引用,这样才能访问子类独有成员
        //这属于向下转型,是强制类型转换
        // 抓一只动物来
        if (a instanceof Person){
            // 表示可以强转
            Person p = (Person) a;
            p.addMoney();
        }

        a.shout();
        // 收集研究
    }
}
class Animal{
    public void shout(){
        System.out.println("叫!");
    }
}
class Cat extends Animal{
    @Override
    public void shout() {
        System.out.println("喵喵喵喵!");
    }
}
class Dog extends Animal{
    @Override
    public void shout() {
        System.out.println("汪汪汪!");
    }
}
class Pig extends Animal{
    @Override
    public void shout() {
        System.out.println("😒");
    }
}
class Person extends Animal{
    @Override
    public void shout() {
        System.out.println("复读,真香,鸽子");
    }

    // 叫之前,得加钱
    public void addMoney(){
        System.out.println("加钱!");
    }
}